home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / larn.lha / global.c < prev    next >
C/C++ Source or Header  |  1995-11-19  |  17KB  |  661 lines

  1. /*  global.c
  2.  *
  3.  *  raiselevel()        subroutine to raise the player one level
  4.  *  loselevel()         subroutine to lower the player by one level
  5.  *  raiseexperience(x)  subroutine to increase experience points
  6.  *  loseexperience(x)   subroutine to lose experience points
  7.  *  losehp(x)           subroutine to remove hit points from the player
  8.  *  losemhp(x)          subroutine to remove max # hit points from the player
  9.  *  raisehp(x)          subroutine to gain hit points
  10.  *  raisemhp(x)         subroutine to gain maximum hit points
  11.  *  losemspells(x)      subroutine to lose maximum spells
  12.  *  raisemspells(x)     subroutine to gain maximum spells
  13.  *  makemonst(lev)      function to return monster number for a randomly selected monster
  14.  *  positionplayer()    function to be sure player is not in a wall
  15.  *  recalc()            function to recalculate the armor class of the player
  16.  *  quit()              subroutine to ask if the player really wants to quit
  17.  *  more()
  18.  *  take()
  19.  *  drop_object()
  20.  *  enchantarmor()
  21.  *  enchweapon()
  22.  *  pocketfull()
  23.  *  nearbymonst()
  24.  *  stealsomething()
  25.  *  emptyhanded()
  26.  *  creategem()
  27.  *  adjustcvalues()
  28.  *  gettokstr()
  29.  *  getpassword()
  30.  *  getyn()
  31.  *  packweight()
  32.  */
  33.  
  34. #include <ctype.h>
  35. #include "header.h"
  36. #include "larndefs.h"
  37. #include "monsters.h"
  38. #include "objects.h"
  39. #include "player.h"
  40.  
  41. extern int score[],dropflag;
  42. extern short playerx,playery,lastnum;
  43. extern char cheat,level,monstnamelist[];
  44. extern char lastmonst[],*what[],*who[]; 
  45. extern char winner[];
  46. extern char logname[],monstlevel[];
  47. extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
  48.  
  49. #ifdef __STDC__
  50. extern void show3( int );
  51. #else
  52. extern void show3();
  53. #endif
  54.  
  55. /*
  56.     raiselevel()
  57.  
  58.     subroutine to raise the player one level
  59.     uses the skill[] array to find level boundarys
  60.     uses c[EXPERIENCE]  c[LEVEL]
  61.  */
  62. raiselevel()
  63.     {
  64.     if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
  65.     }
  66.  
  67. /*
  68.     loselevel()
  69.  
  70.     subroutine to lower the players character level by one
  71.  */
  72. loselevel()
  73.     {
  74.     if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
  75.     }
  76.  
  77. /*
  78.     raiseexperience(x)
  79.  
  80.     subroutine to increase experience points
  81.  */
  82. raiseexperience(x)
  83.     register long x;
  84.     {
  85.     register int i,tmp;
  86.     i=c[LEVEL]; c[EXPERIENCE]+=x;
  87.     while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL))
  88.         {
  89.         tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;
  90.         c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1)));
  91.         raisemspells((int)rund(3));
  92.         if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2));
  93.         }
  94.     if (c[LEVEL] != i)
  95.         {
  96.         cursors();
  97.         beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]);    /* if we changed levels */
  98.         }
  99.     bottomline();
  100.     }
  101.  
  102. /*
  103.     loseexperience(x)
  104.  
  105.     subroutine to lose experience points
  106.  */
  107. loseexperience(x)
  108.     register long x;
  109.     {
  110.     register int i,tmp;
  111.     i=c[LEVEL];     c[EXPERIENCE]-=x;
  112.     if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
  113.     while (c[EXPERIENCE] < skill[c[LEVEL]-1])
  114.         {
  115.         if (--c[LEVEL] <= 1) c[LEVEL]=1;    /*  down one level      */
  116.         tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */
  117.         losemhp((int)rnd((tmp>0)?tmp:1));   /* lose hpoints */
  118.         if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2));
  119.         losemspells((int)rund(3));              /*  lose spells     */
  120.         }
  121.     if (i!=c[LEVEL])
  122.         {
  123.         cursors();
  124.         beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
  125.         }
  126.     bottomline();
  127.     }
  128.  
  129. /*
  130.     losehp(x)
  131.     losemhp(x)
  132.  
  133.     subroutine to remove hit points from the player
  134.     warning -- will kill player if hp goes to zero
  135.  */
  136. losehp(x)
  137.     register int x;
  138.     {
  139.     if ((c[HP] -= x) <= 0)
  140.         {
  141.         beep(); lprcat("\n");  nap(3000);  died(lastnum);
  142.         }
  143.     }
  144.  
  145. losemhp(x)
  146.     register int x;
  147.     {
  148.     c[HP] -= x;     if (c[HP] < 1)      c[HP]=1;
  149.     c[HPMAX] -= x;  if (c[HPMAX] < 1)   c[HPMAX]=1;
  150.     }
  151.  
  152. /*
  153.     raisehp(x)
  154.     raisemhp(x)
  155.  
  156.     subroutine to gain maximum hit points
  157.  */
  158. raisehp(x)
  159.     register int x;
  160.     {
  161.     if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
  162.     }
  163.  
  164. raisemhp(x)
  165.     register int x;
  166.     {
  167.     c[HPMAX] += x;  c[HP] += x;
  168.     }
  169.  
  170. /*
  171.     raisemspells(x)
  172.  
  173.     subroutine to gain maximum spells
  174. */
  175. raisemspells(x)
  176.     register int x;
  177.     {
  178.     c[SPELLMAX]+=x; c[SPELLS]+=x;
  179.     }
  180.  
  181. /*
  182.     losemspells(x)
  183.  
  184.     subroutine to lose maximum spells
  185. */
  186. losemspells(x)
  187.     register int x;
  188.     {
  189.     if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
  190.     if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
  191.     }
  192.  
  193. /*
  194.     makemonst(lev)
  195.         int lev;
  196.  
  197.     function to return monster number for a randomly selected monster
  198.         for the given cave level    
  199.  */
  200. makemonst(lev)
  201.     register int lev;
  202.     {
  203.     register int tmp,x;
  204.     if (lev < 1)
  205.     lev = 1;
  206.     if (lev > 12)
  207.     lev = 12;
  208.     if (lev < 5)
  209.     tmp=rnd((x=monstlevel[lev-1])?x:1);
  210.     else
  211.         tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4];
  212.  
  213.     while (monster[tmp].genocided && tmp<MAXMONST)
  214.     tmp++; /* genocided? */
  215.     return(tmp);
  216.     }
  217.  
  218. /*
  219.     positionplayer()
  220.  
  221.     Insure player is not in a wall or on top of a monster.  Could be more
  222.     intelligent about what kinds of objects the player can land on.
  223.  */
  224. positionplayer()
  225.     {
  226.     int z, try = 2;
  227.  
  228.     /* set the previous player x,y position to the new one, so that
  229.        clearing the player indicator from the previous location will
  230.        not do the wrong thing.
  231.     */
  232.     oldx = playerx ;
  233.     oldy = playery ;
  234.  
  235.     /* short-circuit the testing if current position empty
  236.     */
  237.     if (!item[playerx][playery] &&
  238.         !mitem[playerx][playery])
  239.         return;
  240.  
  241.     /* make at most two complete passes across the dungeon, looking
  242.        for a clear space.  In most situations, should find a clear
  243.        spot right around the current player position.
  244.     */
  245.     do
  246.         {
  247.  
  248.         /* check all around the player position for a clear space.
  249.         */
  250.         for (z=1; z<9 ; z++)
  251.             {
  252.             int tmpx = playerx + diroffx[z];
  253.             int tmpy = playery + diroffy[z];
  254.             if (!item[tmpx][tmpy] &&
  255.                 !mitem[tmpx][tmpy])
  256.                 {
  257.                 playerx = tmpx ;
  258.                 playery = tmpy ;
  259.                 return;
  260.                 }
  261.             }
  262.  
  263.         /* no clear spots around the player. try another position,
  264.            wrapping around the dungeon.
  265.         */
  266.         if (++playerx >= MAXX-1)
  267.             {
  268.             playerx = 1;
  269.             if (++playery >= MAXY-1)
  270.                 {
  271.                 playery = 1;
  272.                 try--;
  273.                 }
  274.             }
  275.         }
  276.     while (try);
  277.  
  278.     /* no spot found.
  279.     */
  280.     lprcat("Failure in positionplayer\n");
  281.     }
  282.  
  283. /*
  284.     recalc()    function to recalculate the armor class of the player
  285.  */
  286. recalc()
  287.     {
  288.     register int i,j,k;
  289.     c[AC] = c[MOREDEFENSES];
  290.     if (c[WEAR] >= 0)  
  291.         switch(iven[c[WEAR]])
  292.             {
  293.             case OSHIELD:       c[AC] += 2 + ivenarg[c[WEAR]]; break;
  294.             case OLEATHER:      c[AC] += 2 + ivenarg[c[WEAR]]; break;
  295.             case OSTUDLEATHER:  c[AC] += 3 + ivenarg[c[WEAR]]; break;
  296.             case ORING:         c[AC] += 5 + ivenarg[c[WEAR]]; break;
  297.             case OCHAIN:        c[AC] += 6 + ivenarg[c[WEAR]]; break;
  298.             case OSPLINT:       c[AC] += 7 + ivenarg[c[WEAR]]; break;
  299.             case OPLATE:        c[AC] += 9 + ivenarg[c[WEAR]]; break;
  300.             case OPLATEARMOR:   c[AC] += 10 + ivenarg[c[WEAR]]; break;
  301.             case OSSPLATE:      c[AC] += 12 + ivenarg[c[WEAR]]; break;
  302.             }
  303.  
  304.     if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
  305.     if (c[WIELD] < 0)  c[WCLASS] = 0;  else
  306.         {
  307.         i = ivenarg[c[WIELD]];
  308.         switch(iven[c[WIELD]])
  309.             {
  310.             case ODAGGER:    c[WCLASS] =  3 + i;  break;
  311.             case OBELT:      c[WCLASS] =  7 + i;  break;
  312.             case OSHIELD:    c[WCLASS] =  8 + i;  break;
  313.             case OSPEAR:     c[WCLASS] = 10 + i;  break;
  314.             case OFLAIL:     c[WCLASS] = 14 + i;  break;
  315.             case OBATTLEAXE: c[WCLASS] = 17 + i;  break;
  316.             case OLANCE:     c[WCLASS] = 19 + i;  break;
  317.             case OLONGSWORD: c[WCLASS] = 22 + i;  break;
  318.             case O2SWORD:    c[WCLASS] = 26 + i;  break;
  319.             case OSWORD:     c[WCLASS] = 32 + i;  break;
  320.             case OSWORDofSLASHING: c[WCLASS] = 30 + i; break;
  321.             case OHAMMER:    c[WCLASS] = 35 + i;  break;
  322.             default:         c[WCLASS] = 0;
  323.             }
  324.         }
  325.     c[WCLASS] += c[MOREDAM];
  326.  
  327. /*  now for regeneration abilities based on rings   */
  328.     c[REGEN]=1;     c[ENERGY]=0;
  329.     j=0;  for (k=25; k>0; k--)  if (iven[k]) {j=k; k=0; }
  330.     for (i=0; i<=j; i++)
  331.         {
  332.         switch(iven[i])
  333.             {
  334.             case OPROTRING: c[AC]     += ivenarg[i] + 1;    break;
  335.             case ODAMRING:  c[WCLASS] += ivenarg[i] + 1;    break;
  336.             case OBELT:     c[WCLASS] += ((ivenarg[i]<<1)) + 2; break;
  337.  
  338.             case OREGENRING:    c[REGEN]  += ivenarg[i] + 1;    break;
  339.             case ORINGOFEXTRA:  c[REGEN]  += 5 * (ivenarg[i]+1); break;
  340.             case OENERGYRING:   c[ENERGY] += ivenarg[i] + 1;    break;
  341.             }
  342.         }
  343.     }
  344.  
  345.  
  346. /*
  347.     quit()
  348.  
  349.     subroutine to ask if the player really wants to quit
  350.  */
  351. quit()
  352.     {
  353.     register int i;
  354.     cursors();  strcpy(lastmonst,"");
  355.     lprcat("\n\nDo you really want to quit?");
  356.     while (1)
  357.         {
  358.         i=ttgetch();
  359.         if ((i == 'y') || (i == 'Y'))   
  360.             { 
  361.             died(300); 
  362.             return; 
  363.             }
  364.         if ((i == 'n') || (i == 'N') || (i == '\33')) 
  365.             { 
  366.             lprcat(" no"); 
  367.             lflush(); 
  368.             return; 
  369.             }
  370.         lprcat("\n");  
  371.         setbold();  lprcat("Yes");  resetbold();  
  372.         lprcat(" or ");
  373.         setbold();  lprcat("No");   resetbold();  
  374.         lprcat(" please?   Do you want to quit? ");
  375.         }   
  376.     }
  377.  
  378. /*
  379.     function to ask --more--. If the user enters a space, returns 0.  If user
  380.     enters Escape, returns 1.  If user enters alphabetic, then returns that
  381.     value.
  382.  */
  383. more(select_allowed)
  384. char select_allowed;
  385.     {
  386.     register int i;
  387.  
  388.     lprcat("\n  --- press ");  standout("space");  lprcat(" to continue --- ");
  389.     if (select_allowed)
  390.         lprcat("letter to select --- ");
  391.  
  392.     while (TRUE)
  393.         {
  394.         if ((i=ttgetch()) == ' ' || i == '\n')
  395.             return 0 ;
  396.         if (i== '\x1B')
  397.             return 1 ;
  398.     if (select_allowed)
  399.         {
  400.         if (isupper(i))
  401.         i = tolower(i);
  402.         if ( i >= 'a' && i <= 'z' || i == '.' )
  403.         return i;
  404.         }
  405.         }
  406.     }
  407.  
  408. /*
  409.     function to enchant armor player is currently wearing
  410.  */
  411. enchantarmor()
  412.     {
  413.     register int tmp;
  414.     if (c[WEAR]<0) { if (c[SHIELD] < 0)
  415.         { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
  416.                     else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } }
  417.     tmp = iven[c[WEAR]];
  418.     if (tmp!=OSCROLL) if (tmp!=OPOTION)  { ivenarg[c[WEAR]]++;  bottomline(); }
  419.     }
  420.  
  421. /*
  422.     function to enchant a weapon presently being wielded
  423.  */
  424. enchweapon()
  425.     {
  426.     register int tmp;
  427.     if (c[WIELD]<0)
  428.         { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
  429.     tmp = iven[c[WIELD]];
  430.     if (tmp!=OSCROLL) if (tmp!=OPOTION)
  431.         { ivenarg[c[WIELD]]++;
  432.           if (tmp==OCLEVERRING) c[INTELLIGENCE]++;  else
  433.           if (tmp==OSTRRING)    c[STREXTRA]++;  else
  434.           if (tmp==ODEXRING)    c[DEXTERITY]++;       bottomline(); }
  435.     }
  436.  
  437. /*
  438.     function to return 1 if a monster is next to the player else returns 0
  439.  */
  440. nearbymonst()
  441.     {
  442.     register int tmp,tmp2;
  443.     for (tmp=playerx-1; tmp<playerx+2; tmp++)
  444.         for (tmp2=playery-1; tmp2<playery+2; tmp2++)
  445.             if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
  446.     return(0);
  447.     }
  448.  
  449. /*
  450.     function to steal an item from the players pockets
  451.     returns 1 if steals something else returns 0
  452.  */
  453. stealsomething()
  454.     {
  455.     register int i,j;
  456.     j=100;
  457.     while (1)
  458.         {
  459.         i=rund(26);
  460.         if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i)
  461.             {
  462.             show3(i);
  463.             adjustcvalues(iven[i],ivenarg[i]);  iven[i]=0; return(1);
  464.             }
  465.         if (--j <= 0) return(0);
  466.         }
  467.     }
  468.  
  469. /*
  470.     function to return 1 is player carrys nothing else return 0
  471.  */
  472. emptyhanded()
  473.     {
  474.     register int i;
  475.     for (i=0; i<26; i++)
  476.         if (iven[i]) if (i!=c[WIELD]) if (i!=c[WEAR]) if (i!=c[SHIELD]) return(0);
  477.     return(1);
  478.     }
  479.  
  480. /*
  481.     function to create a gem on a square near the player
  482.  */
  483. creategem()
  484.     {
  485.     register int i,j;
  486.     switch(rnd(4))
  487.         {
  488.         case 1:  i=ODIAMOND;    j=50;   break;
  489.         case 2:  i=ORUBY;       j=40;   break;
  490.         case 3:  i=OEMERALD;    j=30;   break;
  491.         default: i=OSAPPHIRE;   j=20;   break;
  492.         };
  493.     createitem(i,rnd(j)+j/10);
  494.     }
  495.  
  496. /*
  497.     function to change character levels as needed when dropping an object
  498.     that affects these characteristics
  499.  */
  500. adjustcvalues(itm,arg)
  501.     int itm,arg;
  502.     {
  503.     register int flag;
  504.     flag=0;
  505.     switch(itm)
  506.         {
  507.         case ODEXRING:  c[DEXTERITY] -= arg+1;  flag=1; break;
  508.         case OSTRRING:  c[STREXTRA]  -= arg+1;  flag=1; break;
  509.         case OCLEVERRING: c[INTELLIGENCE] -= arg+1;  flag=1; break;
  510.         case OHAMMER:   c[DEXTERITY] -= 10; c[STREXTRA] -= 10;
  511.                         c[INTELLIGENCE] += 10; flag=1; break;
  512.         case OSWORDofSLASHING:  c[DEXTERITY] -= 5;  flag=1; break;
  513.         case OORBOFDRAGON:      --c[SLAYING];       return;
  514.         case OSPIRITSCARAB:     --c[NEGATESPIRIT];  return;
  515.         case OCUBEofUNDEAD:     --c[CUBEofUNDEAD];  return;
  516.         case ONOTHEFT:          --c[NOTHEFT];       return;
  517.         case OLANCE:        c[LANCEDEATH]=0;    return;
  518.         case OPOTION:   case OSCROLL:   return;
  519.  
  520.         default:    flag=1;
  521.         };
  522.     if (flag) bottomline();
  523.     }
  524.  
  525. /*
  526.     function to ask user for a password (no echo)
  527.     returns 1 if entered correctly, 0 if not
  528.  */
  529. static char gpwbuf[33];
  530. getpassword()
  531.     {
  532.     register int i,j;
  533.     register char *gpwp;
  534.     extern char *password;
  535.     scbr(); /*  system("stty -echo cbreak"); */
  536.     gpwp = gpwbuf;  lprcat("\nEnter Password: "); lflush();
  537.     i = strlen(password);
  538.     for (j=0; j<i; j++) 
  539.         *gpwp++ = ttgetch();
  540.     gpwbuf[i]=0;
  541.     sncbr(); /* system("stty echo -cbreak"); */
  542.     if (strcmp(gpwbuf,password) != 0)
  543.         {   lprcat("\nSorry\n");  lflush(); return(0);  }
  544.     else  return(1);
  545.     }
  546.  
  547. /*
  548.     subroutine to get a yes or no response from the user
  549.     returns y or n
  550.  */
  551. getyn()
  552.     {
  553.     register int i=0;
  554.     while (i!='y' && i!='n' && i!='\33')
  555.     i=ttgetch();
  556.     return(i);
  557.     }
  558.  
  559. /*
  560.     function to calculate the pack weight of the player
  561.     returns the number of pounds the player is carrying
  562.  */
  563. packweight()
  564.     {
  565.     register int i, j=25, k;
  566.  
  567.     k=c[GOLD]/1000;
  568.     while ((iven[j]==0) && (j>0))
  569.     --j;
  570.     for (i=0; i<=j; i++)
  571.         switch(iven[i])
  572.             {
  573.         case 0:
  574.         break;
  575.         case OSSPLATE:
  576.         case OPLATEARMOR:
  577.         k += 40;
  578.         break;
  579.         case OPLATE:
  580.         k += 35;
  581.         break;
  582.         case OHAMMER:
  583.         k += 30;
  584.         break;
  585.         case OSPLINT:
  586.         k += 26;
  587.         break;
  588.         case OSWORDofSLASHING:
  589.         case OCHAIN:
  590.         case OBATTLEAXE:
  591.         case O2SWORD:
  592.         k += 23;
  593.         break;
  594.         case OLONGSWORD:
  595.         case OSWORD:
  596.         case ORING:
  597.         case OFLAIL:
  598.         k += 20;
  599.         break;
  600.         case OLANCE:
  601.         case OSTUDLEATHER:
  602.         k += 15;
  603.         break;
  604.         case OLEATHER:
  605.         case OSPEAR:
  606.         k += 8;
  607.         break;
  608.         case OORBOFDRAGON:
  609.         case OBELT:
  610.         k += 4;
  611.         break;
  612.         case OSHIELD:
  613.         k += 7;
  614.         break;
  615.         case OCHEST:
  616.         k += 30 + ivenarg[i];
  617.         break;
  618.         default:
  619.         k++;
  620.         break;
  621.             };
  622.     return(k);
  623.     }
  624.  
  625. #ifndef MACRORND
  626.     /* macros to generate random numbers   1<=rnd(N)<=N   0<=rund(N)<=N-1 */
  627. rnd(x)
  628.     int x;
  629.     {
  630.     return((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1);
  631.     }
  632.  
  633. rund(x)
  634.     int x;
  635.     {
  636.     return((((lrandx=lrandx*1103515245+12345)>>7)%(x))  );
  637.     }
  638. #endif MACRORND
  639.  
  640. #if 0
  641. /*
  642.     function to read a string from token input "string"
  643.     returns a pointer to the string
  644.  */
  645. gettokstr(str)
  646.     register char *str;
  647.     {
  648.     register int i,j;
  649.     i=50;
  650.     while ((ttgetch() != '"') && (--i > 0));
  651.     i=36;
  652.     while (--i > 0)
  653.         {
  654.         if ((j=ttgetch()) != '"') *str++ = j;  else i=0;
  655.         }
  656.     *str = 0;
  657.     i=50;
  658.     if (j != '"') while ((ttgetch() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
  659.     }
  660. #endif
  661.